package com.tanhua.dubbo.api;

import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.core.query.UpdateDefinition;

import java.util.ArrayList;
import java.util.List;

/**
 * 评论管理-服务接口实现类
 */
@DubboService
public class CommentApiImpl implements CommentApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 评论列表查询
     */
    @Override
    public PageResult<Comment> commentsList(Long page, Long pageSize, String movementId) {
        //定义返回PageResult<Comment>
        Query query = new Query();
        query.addCriteria(
                Criteria.where("publishId").is(new ObjectId(movementId))
                        .and("commentType").is(CommentType.COMMENT.getType())
        );
        //1查询总记录数
        long counts = mongoTemplate.count(query, Comment.class);
        long start = (page - 1) * pageSize;
        //2查询当前页面需要展示的数据
        List<Comment> commentList = new ArrayList<>();
        if (counts > start) { //20 > 27
            //构造分页limit 0,3
            query.limit(pageSize.intValue());//每页查询几条
            query.skip(start);//跳过1条数据
            //query.with(PageRequest.of(page-1,pageSize));
            query.with(Sort.by(Sort.Direction.DESC, "created"));
            commentList = mongoTemplate.find(query, Comment.class);
        }
        return new PageResult<>(page, pageSize, counts, commentList);
    }

    /**
     * 评论-提交 动态点赞 动态喜欢
     */
    @Override
    public Integer add(Comment comment) {
        //1 补全评论对象 ，调用insert保存评论对象
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(comment.getPublishId()));//动态主键id
        Movement movement = mongoTemplate.findOne(query, Movement.class);
        Long publishUserId = movement.getUserId();//被评论人的ID
        comment.setPublishUserId(publishUserId);//设置被评论人的id
        comment.setCreated(System.currentTimeMillis());//评论时间
        mongoTemplate.insert(comment);
        //2 根据动态id更新动态表评论数量+1

        //方式一：有两个步骤
        //mongoTemplate.updateFirst(query,update,Comment.class); update 语句
        //mongoTemplate.findOne(xxx) select 语句
        //方式二：直接一个步骤搞定
        Update updateOne = new Update();//更新的值
        updateOne.inc(getCollName(comment.getCommentType()), 1);//可以根据评论类型 更新不同的xx数量
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();//更新值之后返回最新的值
        findAndModifyOptions.returnNew(true);//返回最新的修改的值
        Movement mm = mongoTemplate.findAndModify(query, updateOne, findAndModifyOptions, Movement.class);
        //3 返回评论数量
        return mm.statisCount(comment.getCommentType());
    }


    /**
     * 动态取消点赞 动态取消喜欢
     */
    @Override
    public Integer remove(Comment comment) {
        //1 动态取消点赞 动态取消喜欢
        Query removeQuery = new Query();
        removeQuery.addCriteria(
                Criteria.where("publishId").is(comment.getPublishId())
                        .and("commentType").is(comment.getCommentType())
                        .and("userId").is(comment.getUserId())
        );
        mongoTemplate.remove(removeQuery, Comment.class);
        //2 根据动态id更新动态表评论数量 喜欢数量 -1
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(comment.getPublishId()));//动态主键id
        Update updateOne = new Update();//更新的值
        updateOne.inc(getCollName(comment.getCommentType()), -1);//可以根据评论类型 更新不同的xx数量
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();//更新值之后返回最新的值
        findAndModifyOptions.returnNew(true);//返回最新的修改的值
        Movement mm = mongoTemplate.findAndModify(query, updateOne, findAndModifyOptions, Movement.class);
        //3 返回评论数量
        return mm.statisCount(comment.getCommentType());
    }

    /**
     * 通过评论类型，获取要更新的动态表中的列名
     *
     * @param commentType
     * @return
     */
    private String getCollName(int commentType) {
        if (CommentType.LIKE.getType() == commentType) {
            return "likeCount";
        } else if (CommentType.COMMENT.getType() == commentType) {
            return "commentCount";
        } else {
            return "loveCount";
        }
    }

    /**
     *动态评论内容-点赞
     */
    @Override
    public Integer addLike(String commentId) {

        //1.对likecount进行加1 返回点赞总数
        Update updateOne = new Update();//更新的值
        updateOne.inc("likeCount", 1);//可以根据评论类型 更新不同的xx数量
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();//更新值之后返回最新的值
        findAndModifyOptions.returnNew(true);//返回最新的修改的值
        Query query = new Query(Criteria.where("_id").is(commentId));
        Comment mm = mongoTemplate.findAndModify(query, updateOne, findAndModifyOptions, Comment.class);

        Integer likeCount = mm.getLikeCount();

        return likeCount;
    }

    /**
     *动态评论内容-点赞取消
     */
    @Override
    public Integer dislike(String commentId) {
        //1.对likecount进行-1 返回点赞总数
        Update updateOne = new Update();//更新的值
        updateOne.inc("likeCount", -1);//可以根据评论类型 更新不同的xx数量
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();//更新值之后返回最新的值
        findAndModifyOptions.returnNew(true);//返回最新的修改的值
        Query query = new Query(Criteria.where("_id").is(commentId));
        Comment mm = mongoTemplate.findAndModify(query, updateOne, findAndModifyOptions, Comment.class);

        Integer likeCount = mm.getLikeCount();

        return likeCount;
    }


    /**
     * 小视频评论发布
     * @param comment
     */
    @Override
    public Integer addVideo(Comment comment) {
        //1 补全评论对象 ，调用insert保存评论对象
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(comment.getPublishId()));//动态主键id
        Video movement = mongoTemplate.findOne(query, Video.class);
        Long publishUserId = movement.getUserId();//被评论人的ID
        comment.setPublishUserId(publishUserId);//设置被评论人的id
        comment.setCreated(System.currentTimeMillis());//评论时间
        mongoTemplate.insert(comment);
        //2 根据动态id更新动态表评论数量+1

        //方式一：有两个步骤
        //mongoTemplate.updateFirst(query,update,Comment.class); update 语句
        //mongoTemplate.findOne(xxx) select 语句
        //方式二：直接一个步骤搞定
        Update updateOne = new Update();//更新的值
        updateOne.inc(getCollName(comment.getCommentType()), 1);//可以根据评论类型 更新不同的xx数量
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();//更新值之后返回最新的值
        findAndModifyOptions.returnNew(true);//返回最新的修改的值
        Video mm = mongoTemplate.findAndModify(query, updateOne, findAndModifyOptions, Video.class);
        //3 返回评论数量
        return mm.getCommentCount();
    }
}
